﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace MyUtils.Performance
{
	/// <summary>
	/// Simple custom tools for measuring performance
	/// </summary>
	/// <example>
	/// // Profiling is disabled by default
	/// ProfilingHelper.EnableProfiling();
	/// using (P.N)
	/// {
	/// 	Thread.Sleep(100);
	/// }
	/// using (P.S("test2"))
	/// {
	/// 	Thread.Sleep(200);
	/// }
	/// // Force show statistics (it is logged every 5 seconds, but you can force it to log)
	/// Console.WriteLine(ProfilingHelper.GetLog());
	/// 
	/// // OUTPUT:
	/// // --------------------
	/// // 00:00:00.1970580         - test2
	/// // 00:00:00.0966199         - Noname Sections
	/// // Press any key to continue . . .
	/// </example>
	public static class ProfilingHelper
	{
		static readonly Lazy<ProfilingHelperInstance> _defaultLazy = new Lazy<ProfilingHelperInstance>(() => new ProfilingHelperInstance());
		internal static bool Enabled;

		static internal readonly List<ProfilingHelperInstance> Instances = new List<ProfilingHelperInstance>();

		public static ProfilingHelperInstance Default
		{
			get
			{
				return _defaultLazy.Value;
			}
		}

		static public void Clear()
		{
			if (Enabled && _defaultLazy.IsValueCreated)
			{
				Default.Clear();
			}
		}

#if !PocketPC
		public static void ShowLogModal()
		{
			Default.ShowLogModal();
		}
#endif

		public static void EnableProfiling()
		{
			Enabled = true;
			lock (Instances)
			{
				foreach (var profilingHelperInstance in Instances)
				{
					profilingHelperInstance.StartAutoFlusher();
				}
			}
		}

		public static IDisposable Section(string sectionName)
		{
			if (Enabled)
			{
				return Default.Section(sectionName);
			}
			return null;
		}

		public static string GetLog()
		{
			if (Enabled)
			{
				if (_defaultLazy.IsValueCreated)
				{
					return Default.GetLog();
				}
				return "Default profiling helper instance never used. Use ProfilingHelper.Default OR P.D OR P.S OR P.N for manual instrumentation";
			}
			return "Profiling disabled. Use " + typeof(ProfilingHelper).Name + ".EnableProfiling()";
		}

		public static void FlushLog()
		{
			if (Enabled && _defaultLazy.IsValueCreated)
			{
				Default.FlushLog();
			}
		}

		/// <summary>Do not call this method.</summary>
		[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "b")]
		[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "a")]
		[Obsolete("Do not call this method", true)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public new static bool Equals(object a, object b)
		{
			throw new InvalidOperationException("Do not call this method");
		}

		/// <summary>Do not call this method.</summary>
		[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "b")]
		[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "a")]
		[Obsolete("Do not call this method", true)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public new static bool ReferenceEquals(object a, object b)
		{
			throw new InvalidOperationException("Do not call this method");
		}

	}
}